/********************************************************************
	TABAL ENGINE - 2012/11/13
	author:		Marc Cuscullola
	
	purpose:	Defines the method to render the renderable vertexs
*********************************************************************/
#pragma once

#ifndef __NON_INDEXED_VERTEXS__INCLUDED_H__
#define __NON_INDEXED_VERTEXS__INCLUDED_H__

#include "RenderableVertexs.h"
#include "Effects\EffectTechnique.h"
#include "RenderManager.h"
#include "VertexType.h"

template<class T>
class CNonIndexedVertexs : public CRenderableVertexs
{
public:
	//-------------------------------------------------
	CNonIndexedVertexs(CRenderManager* _pRM, void* _pVertexAddress, uint32 _uVertexCount, VERTEX_TYPOLOGY _topology = TRIANGLE_LIST)
		: m_Topology(_topology)
		, m_uVertexCount(_uVertexCount)
	{
		D3D11_BUFFER_DESC bd;
		ZeroMemory(&bd, sizeof(bd));
		bd.Usage = D3D11_USAGE_DEFAULT;
		bd.ByteWidth = GetVertexSize() * _uVertexCount;
		bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		bd.CPUAccessFlags = 0;

		D3D11_SUBRESOURCE_DATA InitData;
		ZeroMemory(&InitData, sizeof(InitData));
		InitData.pSysMem = _pVertexAddress;
		HRESULT hr = _pRM->GetDevice()->CreateBuffer(&bd, &InitData, &m_pVertexBuffer);
		assert(SUCCEEDED(hr));
	}

	//-------------------------------------------------
	~CNonIndexedVertexs()
	{

	}

	//-------------------------------------------------
	void Render(CRenderManager* _pRM, CEffectTechnique* _pTechnique) const
	{
		// Set Vertex Buffer
		UINT stride = sizeof(T);
		UINT offset = 0;
		m_pDeviceContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);

		// Set topology
		m_pDeviceContext->IASetPrimitiveTopology(m_Topology);

		// Render
		l_pTechnique->BeginRender();

		D3DX11_TECHNIQUE_DESC desc;
		_pTechnique->GetD3DTechnique()->GetDesc(&desc);
		ID3DX11EffectPass *l_pEffectPass;
		for(uint8 i=0; i<desc.Passes; ++i)
		{
			// Get the current pass
			l_pEffectPass = _pTechnique->GetD3DTechnique()->GetPassByIndex(i);
			assert(l_pEffectPass && l_pEffectPass->IsValid());

			l_pEffectPass->Apply(0, m_pDeviceContext);
			m_pDeviceContext->Draw(m_uVertexCount, 0);
		}
	}

	//-------------------------------------------------
	inline uint16	GetVertexType() const	{ return T::GetVertexType(); }
	inline uint32	GetVertexSize()	const	{ return sizeof(T); }
	inline uint32	GetIndexSize()	const	{ return 0; }
};

#endif //__NON_INDEXED_VERTEXS__INCLUDED_H__